// 实现同一个Promise实例调用多次then方法（含有异步代码场景下）

// 维护三种状态
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

class MyPromise {


	// executor 执行器函数，参数为resolve函数，reject函数
	constructor(executor) { //executor立即执行
		executor(this.resolve, this.reject);
	}

	status = PENDING;// 默认状态
	value = undefined;//成功之后的值 - 使用方传入
	reason = undefined;//失败的原因 - 使用方传入

	successCallback = [];//成功回调
	failCallback = [];// 失败回调


	// 直接调用一个函数(不使用点调用)，那么该函数中的this指向window或undefiend
	// 注意：函数作为类的属性，通常使用箭头函数,这样，直接调用函数时(不使用点调用)，该函数中的this就始终指向该对象的实例
	resolve = value => {
		this.value = value;
		// 保证状态只能被修改一次
		if (this.status !== PENDING) {
			return;
		}
		this.status = FULFILLED;
		// 把所有调用了then方法的回调函数统统执行一遍
		while (this.successCallback.length) this.successCallback.shift()(this.value);
	};
	reject = reason => {
		this.reason = reason;
		// 保证状态只能被修改一次
		if (this.status !== PENDING) {
			return;
		}
		this.status = REJECTED;
		// 把所有调用了then方法的回调函数统统执行一遍
		while (this.failCallback.length) this.failCallback.shift()(this.reason);
	};

	// then是被定义在原型对象中的，在对象的原型对象中定义函数then的写法: then(){} ; 非箭头函数
	// 判断状态，并决定执行resolve还是reject
	then(successCallback, failCallback) {
		if (this.status === FULFILLED) {
			successCallback(this.value);
		} else if (this.status === REJECTED) {
			failCallback(this.reason);
		} else {
			// 此处如果执行，说明一定存在异步代码
			// PENDING状态
			this.successCallback.push(successCallback);
			this.failCallback.push(failCallback);
		}
	}
}

module.exports = MyPromise;